home *** CD-ROM | disk | FTP | other *** search
/ ...taking it to the Macs! / ...taking it to the Macs!.iso / Extras / ActiveX Mac SDK / ActiveX SDK / Common / CXEnumGeneric.cpp < prev    next >
Encoding:
Text File  |  1997-01-02  |  5.0 KB  |  238 lines  |  [TEXT/????]

  1. //
  2. //  CXEnumGeneric.cpp
  3. //
  4. //  Copyright (C) Microsoft Corporation, 1996
  5. //
  6. //  Standard implementation of an enumerator interface.
  7.  
  8. #define FAR
  9. #include "config.h"
  10.  
  11. #include <ole2.h>
  12. #include <dispatch.h>
  13. #include <wintypes.h>
  14. #include "CXEnumGeneric.h"
  15. #include "debug.h"
  16.  
  17. void ReleaseInterfacePtrs(LPUNKNOWN *punkArray, ULONG cElements);
  18. void CopyInterfacePtr(LPUNKNOWN *pTo, LPUNKNOWN *pFrom);
  19. void CopyFORMATETC(LPFORMATETC pTo, LPFORMATETC pFrom);
  20.  
  21.  
  22. CXEnumGeneric::CXEnumGeneric(LPVOID pvArray, ULONG cElements, LPENUMTYPE
  23.     penumtype)
  24. {
  25.     //  Our implementation of the "new" operator will zero the structure so we
  26.     //  don't have to explicitly zero/null anything.
  27.     m_cRef = 1;
  28.     m_pvArray = pvArray;
  29.     m_cElements = cElements;
  30.     m_CurrentElement = 0;
  31.     m_penumtype = penumtype;
  32.     m_pClonedFrom = NULL;
  33. }
  34.  
  35. CXEnumGeneric::~CXEnumGeneric()
  36. {
  37.     if (m_pClonedFrom != NULL) {
  38.         m_pClonedFrom->Release();
  39.     } else {
  40.         if (m_pvArray != NULL) {
  41.             if (m_penumtype->pfnReleaseArray != NULL)
  42.                 m_penumtype->pfnReleaseArray(m_pvArray, m_cElements);
  43.             CoTaskMemFree(m_pvArray);
  44.         }
  45.     }
  46. }
  47.  
  48. //
  49. //  CXEnumGeneric::IUnknown::QueryInterface
  50. //
  51. //  Returns a pointer to the specified interface on a component to which a
  52. //  client currently holds an interface pointer.
  53. //
  54.  
  55. STDMETHODIMP
  56. CXEnumGeneric::QueryInterface(REFIID riid, LPVOID *ppvObj)
  57. {
  58.     HRESULT hr;
  59.     LPVOID pv;
  60.  
  61.     if (riid == IID_IUnknown || riid == *m_penumtype->piid) {
  62.         pv = (LPVOID)(LPENUMGENERIC) this;
  63.         ++m_cRef;
  64.         hr = ResultFromScode(S_OK);
  65.     } else {
  66.         pv = NULL;
  67.         hr = ResultFromScode(E_NOINTERFACE);
  68.     }
  69.  
  70.     *ppvObj = pv;
  71.     return hr;
  72. }
  73.  
  74. //
  75. //  CXEnumGeneric::IUnknown::AddRef
  76. //
  77. //  Increments the reference count for the calling interface.
  78. //
  79.  
  80. STDMETHODIMP_(ULONG)
  81. CXEnumGeneric::AddRef(void)
  82. {
  83.     return ++m_cRef;
  84. }
  85.  
  86. //
  87. //  CXEnumGeneric::IUnknown::Release
  88. //
  89. //  Decrements the reference count for the calling interface on a object.  If
  90. //  the reference count on the object falls to zero, the object is freed.
  91. //
  92.  
  93. STDMETHODIMP_(ULONG)
  94. CXEnumGeneric::Release(void)
  95. {
  96.     if (--m_cRef != 0)
  97.         return m_cRef;
  98.  
  99.     delete this;
  100.     return 0;
  101. }
  102.  
  103. //
  104. //  CXEnumGeneric::IEnumGeneric::Next
  105. //
  106.  
  107. STDMETHODIMP
  108. CXEnumGeneric::Next(ULONG celt, LPVOID rgelt, ULONG *pceltFetched)
  109. {
  110.     HRESULT hr;
  111.     ULONG celtFetched;
  112.     ULONG current;
  113.     LPBYTE pFrom;
  114.     LPBYTE pTo;
  115.  
  116.     if (m_CurrentElement + celt <= m_cElements) {
  117.         hr = ResultFromScode(S_OK);
  118.         celtFetched = celt;
  119.     } else {
  120.         hr = ResultFromScode(S_FALSE);
  121.         celtFetched = m_cElements - m_CurrentElement;
  122.     }
  123.  
  124.     if (pceltFetched != NULL)
  125.         *pceltFetched = celtFetched;
  126.  
  127.     pTo = (LPBYTE) rgelt;
  128.     pFrom = ((LPBYTE) m_pvArray) + (m_CurrentElement * m_penumtype->cbElement);
  129.  
  130.     for (current = 0; current < celtFetched; current++) {
  131.         m_penumtype->pfnCopyElement((LPVOID) pTo, (LPVOID) pFrom);
  132.         pTo += m_penumtype->cbElement;
  133.         pFrom += m_penumtype->cbElement;
  134.         m_CurrentElement++;
  135.     }
  136.  
  137.     return hr;
  138. }
  139.  
  140. //
  141. //  CXEnumGeneric::IEnumGeneric::Skip
  142. //
  143.  
  144. STDMETHODIMP
  145. CXEnumGeneric::Skip(ULONG celt)
  146. {
  147.     HRESULT hr;
  148.  
  149.     if (m_CurrentElement + celt <= m_cElements) {
  150.         m_CurrentElement += celt;
  151.         hr = ResultFromScode(S_OK);
  152.     } else {
  153.         m_CurrentElement = m_cElements;
  154.         hr = ResultFromScode(S_FALSE);
  155.     }
  156.  
  157.     return hr;
  158. }
  159.  
  160. //
  161. //  CXEnumGeneric::IEnumGeneric::Reset
  162. //
  163.  
  164. STDMETHODIMP
  165. CXEnumGeneric::Reset(void)
  166. {
  167.     m_CurrentElement = 0;
  168.     return ResultFromScode(S_OK);
  169. }
  170.  
  171. //
  172. //  CXEnumGeneric::IEnumGeneric::Clone
  173. //
  174.  
  175. STDMETHODIMP
  176. CXEnumGeneric::Clone(LPENUMGENERIC *ppenum)
  177. {
  178.     HRESULT hr;
  179.     CXEnumGeneric *penumClone;
  180.  
  181.     //  The clone will hold a reference to our object; m_pvArray will go away
  182.     //  when all clones and the original object have a total reference count of
  183.     //  zero.
  184.     if ((penumClone = new CXEnumGeneric(m_pvArray, m_cElements, m_penumtype)) !=
  185.         NULL) {
  186.         penumClone->m_pClonedFrom = this;
  187.         ++m_cRef;
  188.         *ppenum = (LPENUMGENERIC) penumClone;
  189.         hr = ResultFromScode(S_OK);
  190.     } else {
  191.         hr = ResultFromScode(E_OUTOFMEMORY);
  192.     }
  193.  
  194.     return hr;
  195. }
  196.  
  197. /////////////////////////////////////////////////////////////////////////////
  198. //  IEnumUnknown support
  199.  
  200. void
  201. CopyInterfacePtr(LPUNKNOWN *pTo, LPUNKNOWN *pFrom)
  202. {
  203.     *pTo = *pFrom;
  204.     (*pTo)->AddRef();
  205. }
  206.  
  207. void
  208. ReleaseInterfacePtrs(LPUNKNOWN *punkArray, ULONG cElements)
  209. {
  210.     for (ULONG current = 0; current < cElements; current++)
  211.         punkArray[current]->Release();
  212. }
  213.  
  214. ENUMTYPE g_EnumUnknown =
  215. {
  216.     &IID_IEnumUnknown,
  217.     sizeof(LPUNKNOWN),
  218.     (LPFNENUMCOPYELEMENT) CopyInterfacePtr,
  219.     (LPFNENUMRELEASEARRAY) ReleaseInterfacePtrs
  220. };
  221.  
  222. /////////////////////////////////////////////////////////////////////////////
  223. //  IEnumWINFORMATETC support
  224.  
  225. void
  226. CopyFORMATETC(LPFORMATETC pTo, LPFORMATETC pFrom)
  227. {
  228.     *pTo = *pFrom;
  229. }
  230.  
  231. ENUMTYPE g_EnumFORMATETC =
  232. {
  233.     &IID_IEnumFORMATETC,
  234.     sizeof(FORMATETC),
  235.     (LPFNENUMCOPYELEMENT) CopyFORMATETC,
  236.     (LPFNENUMRELEASEARRAY) NULL
  237. };
  238.